#import requests
from urllib.request import urlopen

from cache.cache import cache
from cache.constants import TIDAL_ARTIST, TIDAL_ALBUM
import tidal.artist
import tidal.album
from generic.track_utils import guess_file_name
from generic.utils import print_progress_callback

class TidalTrack:
  def __init__(self, id, title):
    self.id = id
    self.title = title

  def set_raw_data(self, song_data):
    self.id = song_data["id"]
    self.title = song_data["title"]
    # setting artists
    def get_artist(artist_info):
      cache_key = TIDAL_ARTIST % artist_info["id"]
      if cache.has(cache_key):
        artist = cache.get(cache_key)
      else:
        artist = tidal.artist.TidalArtist(artist_info["id"], artist_info["name"])
        cache.set(cache_key, artist)
      return artist
    self.artists = list(map(get_artist, song_data["artists"]))
    # setting album
    album_data = song_data["album"]
    album_cache_key = TIDAL_ALBUM % album_data["id"]
    if cache.has(album_cache_key):
      album = cache.get(album_cache_key)
    else:
      album = tidal.album.TidalAlbum(album_data["id"], album_data["title"])
      cache.set(album_cache_key, album)
    self.album = album
    self.qualities = [song_data["audioQuality"]]

  def get_stream(self, tidal_instance, quality):
    return tidal_instance.get_stream(self.id, quality)

  def stream(self, tidal_instance, output_stream, progress_callback = None):
    track_stream = self.get_stream(tidal_instance, quality)
    self.stream(track_stream, output_stream,
                progress_callback = progress_callback)
  def _stream(self, track_stream, output_stream, progress_callback = None):
    stream = urlopen(track_stream.url)

    length = int(stream.getheader('Content-Length'))
    chunk_size = 8192
    i = 0
    while True:
      chunk = stream.read(chunk_size)
      if progress_callback != None:
        if (i * chunk_size) > length:
          progress_callback(1)
        else:
          progress_callback((i * chunk_size) / length)
      if not chunk:
        break
      output_stream.write(chunk)
      i += 1

  def download(self, tidal_instance, to_file = None,
               progress_callback = lambda p: print(p),
               quality = None, print_progress = False):
    if quality == None:
      quality = self.qualities[len(self.qualities) - 1]
    if to_file == None:
      to_file = guess_file_name(self)
    track_stream = self.get_stream(tidal_instance, quality)
    file_format = ".flac" if ".m4a" not in track_stream.url else ".m4a"
    file_name = to_file + file_format

    with open(file_name, 'wb') as stream:
      self._stream(track_stream,
                   stream, # output stream
                   progress_callback = print_progress_callback \
                   if print_progress else progress_callback)
